import { BattleData } from "../Data/BattleData";
import { CardData } from "../Data/CardData";
import { CardUI } from "../Entity/cardUI";
import { GameUI } from "../UI/gameUI";
import DataManager from "../utils/DataSystem/DataManager";
import { ProbeEventList } from "../utils/EventSystem/EventList";
import EventProp from "../utils/EventSystem/EventProp";
import { StateBlock } from "../utils/StateBlock/StateBlock";
import CardStateBlock from "./CardStateBlock";

/**
 * battle状态机
 */
export default class BattleStateBlock extends StateBlock{

    public static EmptyBattle : BattleData = {
        cost : 0,
        limitCost: 0,
        maxCost : 10,
        hand : [],
        ally : [],
        enemy : [],
        taskText : "空的",
        task : null
    }

    protected InitState: typeof StateBlock = BattleStateBlock_BattleStart;

    public BattleStart : ProbeEventList = new ProbeEventList();
    public AllyTurnStart : ProbeEventList = new ProbeEventList();
    public AllyTurnEnd : ProbeEventList = new ProbeEventList();
    public EnemyTurnStart : ProbeEventList = new ProbeEventList();
    public EnemyTurnEnd : ProbeEventList = new ProbeEventList();

    public handZone : EventProp<Array<CardStateBlock>> = new EventProp();

    public allyZone : EventProp<Array<CardStateBlock>> = new EventProp();

    public enemyZone : EventProp<Array<CardStateBlock>> = new EventProp();

    public WinEvent : ProbeEventList = new ProbeEventList();

    public get allMinions() : Array<CardStateBlock>
    {
        return this.allyZone.Value.concat(this.enemyZone.Value);
    }

    
    public static async AllCardData() : Promise<CardData[]> {
        return await DataManager.Instance.GetData<CardData[]>("CardData");
    }



    /**
     * 战斗初始化数据
     */
    public initBattleData : BattleData = null;

    /**
     * 当前法力消费
      */
    public cost : EventProp<number> = new EventProp();
    /**
     * 法力上限
     */
    public limitCost : EventProp<number> = new EventProp();
    /**
     * 法力上限的上限
     */
    public maxCost : EventProp<number> = new EventProp();
    /**
     * 最大随从数量
     */
    public maxMinionCount : EventProp<number> = new EventProp();

    public EndTurn()
    {
        if(this.currentStateKey == BattleStateBlock_AllyTurn.name)
        {
            this.changeState(BattleStateBlock_EnemyTurn)
        }else if(this.currentStateKey == BattleStateBlock_EnemyTurn.name){
            this.changeState(BattleStateBlock_AllyTurn)
        }
    }

    public CanUseCard(cardData : CardData) : boolean{
        if(this.allyZone.Value.length == this.maxMinionCount.Value)
        {
            return false;
        }else if(cardData.cost > this.cost.Value){
            return false;
        }
        return true;
    }

    /**
     * 尝试使用卡牌
     * @param card 
     */
    public TryUseCard(card : CardStateBlock){
        this.handZone.Value = this.handZone.Value.filter(c => c !== card);
        let list = this.allyZone.Value;
        list.push(card);
        this.allyZone.Value = list;
    }

    /**
     * 尝试攻击
     * @param source 
     * @param target 
     */
    public TryAttack(source : CardStateBlock,target : CardStateBlock){

        source.CardAttacking.DoEvent(source,target);

        source.Health.Value = source.Health.Value - target.Attack.Value;
        target.Health.Value = target.Health.Value - source.Attack.Value;

        source.CardAttacked.DoEvent(source,target);

        this.CheckDead();
    }

    /**
     * 检查去世
     */
    public CheckDead()
    {
        /**
         * 将所有生命值低于0的卡记录为寄
         */
        for (const min of this.allMinions) {
            if(min.Health.Value<=0){
                min.IsDead = true;
            }
        }

        let deadMin = this.allMinions.filter(card => card.IsDead);

        for (const min of deadMin) {
            min.CardDead.DoEvent(null);
        }

        this.allyZone.Value = this.allyZone.Value.filter(card => !card.IsDead);
        this.enemyZone.Value = this.enemyZone.Value.filter(card => !card.IsDead);
    }

    public Start(): void {

        super.Start();
    }

    public Close(): void {
        this.BattleStart.Clear();
        this.AllyTurnStart.Clear();
        this.AllyTurnEnd.Clear();
        this.EnemyTurnStart.Clear();
        this.EnemyTurnEnd.Clear();

        this.allyZone.ClearFunc();
        this.handZone.ClearFunc();
        this.enemyZone.ClearFunc();
        super.Close();
    }

    public NoHandWin(self : BattleStateBlock,value){
        if(self.handZone.Value.length == 0)
        {
            self.Win();
        }
    }

    public NoEnemyWin(self,value){
        if(self.enemyZone.Value.length == 0)
        {
            self.Win();
        }
    }

    public Win(){
       this.WinEvent.DoEvent();
    }

    /**
     *
     */
    constructor() {
        super();
        this.allyZone.InitValue([]);
        this.enemyZone.InitValue([]);
        this.handZone.InitValue([]);

        
    }


}

class BattleStateBlock_StateBase extends StateBlock{
    protected get battle() : BattleStateBlock {
        return this.parent as BattleStateBlock;
    }
}

/**
 * 没有战斗，空状态
 */
class BattleStateBlock_Empty extends BattleStateBlock_StateBase{

}

/**
 * 战斗开始状态
 */
class BattleStateBlock_BattleStart extends BattleStateBlock_StateBase{

    public async onEnter(): Promise<void> {
        if(this.battle.initBattleData == null){
            this.battle.initBattleData = BattleStateBlock.EmptyBattle;
            console.error("Battle : Not Init Battle");
        }
        //  输入初始化数据
        this.battle.cost.InitValue(this.battle.initBattleData.cost);
        this.battle.limitCost.InitValue(this.battle.initBattleData.limitCost);
        this.battle.maxCost.InitValue(this.battle.initBattleData.maxCost);
        this.battle.maxMinionCount.InitValue(7);

        this.battle.BattleStart.DoEvent(null)

        console.log(this.battle.initBattleData);
        //  将初始化手牌转化成手牌
        let list = [];
        for(let data of this.battle.initBattleData.hand){
            let card = await CardStateBlock.CreateFromRuntimeCard(data);
            list.push(card);
        }
        this.battle.handZone.Value = list;
        //  将初始化敌人转化成敌人
        list = [];
        for(let data of this.battle.initBattleData.enemy){
            let card = await CardStateBlock.CreateFromRuntimeCard(data);
            list.push(card);
        }
        this.battle.enemyZone.Value = list;

        list = [];
        for(let data of this.battle.initBattleData.ally){
            let card = await CardStateBlock.CreateFromRuntimeCard(data);
            list.push(card);
        }
        this.battle.allyZone.Value = list;

        if(this.battle.initBattleData.task.event == "NoHand")
        {
            this.battle.handZone.ValueChanged.AddFunc(this.battle.NoHandWin,this.battle);
        }else if(this.battle.initBattleData.task.event == "NoEnemy")
        {
            this.battle.enemyZone.ValueChanged.AddFunc(this.battle.NoEnemyWin,this.battle);
        }

        this.battle.changeState(BattleStateBlock_AllyTurn);
    }

}

/**
 * 我方回合阶段
 */
class BattleStateBlock_AllyTurn extends BattleStateBlock_StateBase{

    public onEnter(): void {
        if(this.battle.limitCost.Value < this.battle.maxCost.Value){
            this.battle.limitCost.Value = this.battle.limitCost.Value + 1;
        }
        this.battle.cost.Value = this.battle.limitCost.Value;
        //  回合开始，重置所有友方攻击次数
        for (const ally of this.battle.allyZone.Value) {
            ally.ResetAttackCount();
        }
        this.battle.AllyTurnStart.DoEvent(null);
    }

    public onExit(): void {
        this.battle.AllyTurnEnd.DoEvent(null);
    }
}

/**
 * 敌方开始阶段
 */
class BattleStateBlock_EnemyTurn extends BattleStateBlock_StateBase{

    public onEnter(): void {
        this.battle.EnemyTurnStart.DoEvent(null);
        this.battle.EndTurn();
    }

    public onExit(): void {
        this.battle.EnemyTurnEnd.DoEvent(null);
    }
}

